package com.ruoyi.source.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.source.api.domain.SrcCity;
import com.ruoyi.source.api.domain.SrcCropInfo;
import com.ruoyi.source.api.domain.SrcLogistics;
import com.ruoyi.source.config.MinioProperties;
import com.ruoyi.source.domain.SrcUsers;
import com.ruoyi.source.mapper.SrcCityMapper;
import com.ruoyi.source.mapper.SrcCropInfoMapper;
import com.ruoyi.source.mapper.SrcLogisticsMapper;
import com.ruoyi.source.mapper.SrcUsersMapper;
import com.ruoyi.source.service.ISrcCropInfoService;
import com.ruoyi.source.utils.MyMinioUtils;
import com.ruoyi.system.api.domain.SysDept;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 农作物信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-07-22
 */
@Service
public class SrcCropInfoServiceImpl extends ServiceImpl<SrcCropInfoMapper,SrcCropInfo> implements ISrcCropInfoService {

@Autowired
private SrcLogisticsMapper srcLogisticsMapper;
    @Autowired
    private SrcCityMapper srcCityMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioProperties minioProperties;

    @Autowired
    private SrcUsersMapper srcUsersMapper;
    /**
     * 查询农作物信息
     * 
     * @param cropId 农作物信息主键
     * @return 农作物信息
     */
    @Override
    public SrcCropInfo selectSrcCropInfoByCropId(Long cropId) {
        return baseMapper.selectById(cropId);
    }

    /**
     * 查询农作物信息列表
     *
     * @return 农作物信息
     */
    @Override
    public List<SrcCropInfo> selectSrcCropInfoList(IPage<SrcCropInfo> iPage,String cropName,Long cropType,Long plantingWay,String plantingYear) {
        return baseMapper.selectSrcCropInfoList(iPage,cropName,cropType,plantingWay,plantingYear);
    }

    /**
     * 新增农作物信息
     * 
     * @param srcCropInfo 农作物信息
     * @return 结果
     */
    @Override
    public int insertSrcCropInfo(SrcCropInfo srcCropInfo) {
        srcCropInfo.setCreateBy(SecurityUtils.getUsername());
        srcCropInfo.setCreateTime(DateUtils.getNowDate());
        Date newDate = DateUtil.offset(srcCropInfo.getPlantCreated(), DateField.MONTH, srcCropInfo.getGrowthCycle());
        srcCropInfo.setPlantEndTime(newDate);
        BigDecimal multiply = srcCropInfo.getPlantRange().multiply(srcCropInfo.getPlantAxe());
        srcCropInfo.setDelivery(multiply);
        return baseMapper.insert(srcCropInfo);
    }

    /**
     * 修改农作物信息
     * 
     * @param srcCropInfo 农作物信息
     * @return 结果
     */
    @Override
    public int updateSrcCropInfo(SrcCropInfo srcCropInfo) {
        srcCropInfo.setUpdateBy(SecurityUtils.getUsername());
        srcCropInfo.setUpdateTime(DateUtils.getNowDate());
        Date newDate = DateUtil.offset(srcCropInfo.getPlantCreated(), DateField.MONTH, srcCropInfo.getGrowthCycle());
        srcCropInfo.setPlantEndTime(newDate);
        BigDecimal multiply = srcCropInfo.getPlantRange().multiply(srcCropInfo.getPlantAxe());
        srcCropInfo.setDelivery(multiply);
        return baseMapper.updateById(srcCropInfo);
    }

    /**
     * 批量删除农作物信息
     * 
     * @param cropIds 需要删除的农作物信息主键
     * @return 结果
     */
    @Override
    public int deleteSrcCropInfoByCropIds(Long[] cropIds) {
        return baseMapper.deleteBatchIds(Arrays.asList(cropIds));
    }

    /**
     * 删除农作物信息信息
     * 
     * @param cropId 农作物信息主键
     * @return 结果
     */
    @Override
    public int deleteSrcCropInfoByCropId(Long cropId) {
        return baseMapper.deleteById(cropId);
    }

    @Override
    public List<SrcCity> selectAddress() {
        if (Boolean.TRUE.equals(redisTemplate.hasKey("city"))){
            System.out.println("拿取缓存内的地区数据");
            return redisTemplate.opsForList().range("city",0,-1);
        }
        List<SrcCity> srcCityList = srcCityMapper.selectList(new LambdaQueryWrapper<>());
        List<SrcCity> srcParentList = srcCityList.stream().filter(ss -> ss.getParentId()==1).collect(Collectors.toList());
        for (SrcCity srcCity : srcParentList) {
            addressRecursion(srcCityList,srcCity);
        }
        redisTemplate.opsForList().leftPushAll("city",srcParentList);
        return srcParentList;
    }

    private void addressRecursion(List<SrcCity> srcCityList, SrcCity srcCity) {
        List<SrcCity> collect = srcCityList.stream().filter(ss -> Objects.equals(ss.getParentId(), srcCity.getCityId())).collect(Collectors.toList());
        if (!collect.isEmpty()){
            srcCity.setChildren(collect);
            for (SrcCity city : collect) {
                addressRecursion(srcCityList,city);
            }
        }
    }

    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        return new MyMinioUtils(minioClient,minioProperties).uploadFile(file);
    }

    @Override
    public AjaxResult batchInsert() {
        long startTime = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        try {
            //生成数据
            List<SrcUsers> userList = new ArrayList<>();
            for (int i = 0; i < 3000000; i++) {
                SrcUsers srcUsers = new SrcUsers();
                srcUsers.setName("张子涵"+i);
                srcUsers.setRemark("老师我们家子涵怎么又报错啦"+i);
                userList.add(srcUsers);
            }
            int batchSize = 20000;
            int fromIndex = 0;
            while (fromIndex< userList.size()){
                int min = Math.min(fromIndex + batchSize, userList.size());
                List<SrcUsers> srcUsers = userList.subList(fromIndex, min);
                fromIndex+=batchSize;
                executorService.execute(()->{
                    try {
                        int rows = srcUsersMapper.batchInsert(srcUsers);
                    }catch (Exception e){

                    }
                });
            }
            executorService.shutdown();
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        }catch (Exception e){

        }



        /*int num = 10000;
        CountDownLatch latch = new CountDownLatch(1);
        List<SrcUsers> userList = new ArrayList<>();
        new Thread(() -> {
            for (int i = 0; i < 3000000; i++) {
                SrcUsers srcUsers = new SrcUsers();
                srcUsers.setName("张子涵"+i);
                srcUsers.setRemark("老师我们家子涵怎么又报错啦"+i);
                userList.add(srcUsers);
            }
            latch.countDown();
        }).start();
        try {
            latch.await();
        } catch (InterruptedException e) {
        }
        //10000条为一批，插入300万条
        List<List<SrcUsers>> partition = Lists.partition(userList, num);
        partition.stream().forEach(user -> {
            int rows = srcCropInfoMapper.batchInsert(user);
        });*/
        long endTime = System.currentTimeMillis();
        System.out.printf("执行时长：%d 毫秒.", (endTime - startTime));
        return AjaxResult.success();
    }

    @Override
    public List<Map<String,Object>> selectCropTypeCount() {
        return baseMapper.selectCropTypeCount();
    }

    @Override
    public List<SysDept> deptList() {
        return baseMapper.deptList();
    }

    @Override
    @Transactional
    public int toadd(SrcLogistics srcLogistics) {
        int i = srcLogisticsMapper.insertSrcLogistics(srcLogistics);
        baseMapper.getbyids(srcLogistics.getGoodsId(),srcLogistics.getGoodsNum());
        return i;
    }
}
